﻿namespace OJS.Services
{
    using OJS.Worker;
    using System.Collections.Generic;
    using System.ServiceModel;
    using System.IO;

    /// <summary>
    /// Thực thi phương thức của giao diện.
    /// ConcurrencyMode: Cho phép nhiều lượt truy cập vào Service cùng một thời điểm
    /// InstanceContextMode: Quy định một thể hiện của Service phục vụ toàn bộ request.
    /// </summary>
    [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, 
        InstanceContextMode = InstanceContextMode.Single)]
    public class SubmitService : ISubmitService
    {
        private static Queue<SubmitDetails> queue = new Queue<SubmitDetails>();
        private static object thislock = new object();
        private static bool isBusy;
        /// <summary>
        /// Thực thi phương thức AddSubmit
        /// </summary>
        /// <param name="sm">Thể hiện của SubmitDetails chứa thông tin về submit</param>
        public void AddSubmit(SubmitDetails sm)
        {
            lock (thislock)
            {
                queue.Enqueue(sm);
                // Đảm bảo lần submit đầu tiên có đủ thời gian để set isBusy = true.
                System.Threading.Thread.Sleep(50);
            }

            if (!isBusy)
            {
                isBusy = true;
                System.Threading.Tasks.Task.Run(() =>
                {
                    List<JudgeResult> jRL = new List<JudgeResult>();
                    Judger judge = new Judger();
                    SubmitDetails s;
                    while (queue.Count > 0)
                    {
                        lock (thislock) 
                        { 
                            s = queue.Dequeue(); 
                        }
                        jRL.Add(judge.DoJudge(s));
                    }
                    // exec SQL insert statement at here
                    // Code below will add to text file.
                    using(StreamWriter writer = File.AppendText(@"D:\result.txt"))
                    {
                        foreach (var i in jRL)
                        {
                            writer.WriteLine(string.Format("{0} + {1} + {2} + {3} + {4} + {5} + {6} + {7}",
                                i.SubmitTime,
                                i.Uid,
                                i.ProblemCode,
                                i.Result,
                                i.Time,
                                i.MemoryConsume,
                                i.Language,
                                i.IsContest));
                        }
                        writer.Flush();
                    }                    
                    isBusy = false;
                });
            }
        }
    }
}